package LockAndCondition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class UseCondition {
	
	private Lock lock = new ReentrantLock();
	private Condition condition1 = lock.newCondition();
	private Condition condition2 = lock.newCondition();
	
	public void method1() {
		try {
			lock.lock();
			System.out.println("当前线程:"+Thread.currentThread().getName()+"进入method1,method1等待....");
			condition1.await();
			
			System.out.println("method1继续执行...");
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public void method2() {
		try {
			lock.lock();
			System.out.println("当前线程:"+Thread.currentThread().getName()+"进入method2,method2等待....");
			condition1.await();
			
			System.out.println("method2继续执行...");
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	
	public void method3() {
		try {
			lock.lock();
			System.out.println("当前线程:"+Thread.currentThread().getName()+"进入method3,唤醒所有Condition1的线程");
			condition1.signalAll();
		} finally {
			lock.unlock();
		}
	}
	
	public void method4() {
		try {
			lock.lock();
			System.out.println("当前线程:"+Thread.currentThread().getName()+"进入method4....method4等待");
			condition2.await();
			System.out.println("method4继续执行");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally {
			lock.unlock();
		}
	}
	
	
	public void method5() {
		try {
			lock.lock();
			System.out.println("当前线程:"+Thread.currentThread().getName()+"进入method5....唤醒condition2");
			condition2.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public static void main(String[] args) {
		final UseCondition uc = new UseCondition();
		
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				uc.method1();// 
			}
		});
		
		Thread t5 = new Thread(new Runnable() {
			public void run() {
				uc.method2();// lock1  --- lock
			}
		});
		
		
				
		
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				uc.method3();  // lock1 --- 通知
			}
		});
		
		Thread t3 = new Thread(new Runnable() {
			public void run() {
				uc.method4();// lock2
			}
		});
		Thread t4 = new Thread(new Runnable() {
			public void run() {
				uc.method5();  // lock2
			}
		});
		
		
		t1.start();//lock1  --- lock
		t5.start();//lock1  --- lock
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		t2.start();//lock1  --- unlock
		
		
		t3.start();//lock2  --- lock
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		t4.start();//lock2  --- unlock
	}
	
	
}
